Imports System
Imports System.ComponentModel
Imports System.Collections
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Diagnostics
Imports DevExpress.CodeRush.Core
Imports DevExpress.CodeRush.PlugInCore
Imports DevExpress.CodeRush.StructuralParser
Imports SP = DevExpress.CodeRush.StructuralParser
Imports DX_Contrib
Imports DX_Contrib.Painting
Imports DX_Contrib.Caching
Imports System.Runtime.Serialization
Imports DevExpress.CodeRush.Diagnostics.General
Imports DevExpress.CodeRush.Win32.RECT
Imports System.Threading

Namespace CR_UnusedVariables
    Public Class LEIterator
        Private Shared UsableTypes() As LanguageElementType = _
                                             {LanguageElementType.Variable, _
                                              LanguageElementType.Parameter, _
                                              LanguageElementType.TypeReferenceExpression, _
                                              LanguageElementType.Method}
#Region "Fields"
        Private mTypeList() As LanguageElementType
        Private mProcessSubNodes As Boolean = True
        Private mProcessDetailNodes As Boolean = False
        Private mDeepSearch As Boolean = True
        Private mRequireVisible As Boolean
        Private RangeElements As LanguageElementCollection
#End Region
#Region "Properties"
        Public Property ProcessSubNodes() As Boolean
            Get
                Return mProcessSubNodes
            End Get
            Set(ByVal Value As Boolean)
                mProcessSubNodes = Value
            End Set
        End Property
        Public Property ProcessDetailNodes() As Boolean
            Get
                Return mProcessDetailNodes
            End Get
            Set(ByVal Value As Boolean)
                mProcessDetailNodes = Value
            End Set
        End Property
        Public Property DeepSearch() As Boolean
            Get
                Return mDeepSearch
            End Get
            Set(ByVal Value As Boolean)
                mDeepSearch = Value
            End Set
        End Property
#End Region
        Public Property RequireVisible() As Boolean
            Get
                Return mRequireVisible
            End Get
            Set(ByVal Value As Boolean)
                mRequireVisible = Value
            End Set
        End Property
        Public Sub New(ByVal TypeList() As LanguageElementType, ByVal DeepSearch As Boolean)
            mTypeList = TypeList
            mDeepSearch = DeepSearch
        End Sub
        Private Delegate Sub ProcessLanguageElement(ByVal LE As LanguageElement)
        Public Function CollectElements(ByVal Range As SourceRange) As LanguageElementCollection
            RangeElements = New LanguageElementCollection
            CodeRush.Source.IterateNodesInRange(Range, AddressOf AddDeepCollectedToRangeElements)
            Return RangeElements
        End Function
        Private Sub AddDeepCollectedToRangeElements(ByVal ea As NodeIterationEventArgs)
            RangeElements.Add(ea.LanguageElement)
            'RangeElements.AddRange(CollectElements(ea.LanguageElement))
        End Sub
        Public Function CollectElements(ByVal StartingElement As LanguageElement) As LanguageElementCollection
            Dim LEC As New LanguageElementCollection
            If mTypeList Is Nothing OrElse LEMatchesTypeList(StartingElement) Then
                LEC.Add(StartingElement)
            End If
            If mDeepSearch AndAlso mProcessSubNodes AndAlso StartingElement.NodeCount > 0 Then
                For Each LE As LanguageElement In StartingElement.Nodes
                    LEC.AddRange(CollectElements(LE))
                Next
            End If
            If mDeepSearch AndAlso mProcessDetailNodes AndAlso StartingElement.DetailNodeCount > 0 Then
                For Each LE As LanguageElement In StartingElement.DetailNodes
                    LEC.AddRange(CollectElements(LE))
                Next
            End If
            Return LEC
        End Function
        Private Function LEMatchesTypeList(ByVal LE As LanguageElement) As Boolean
            For Each ET As LanguageElementType In mTypeList
                If LE.ElementType = ET Then
                    Return True
                End If
            Next
        End Function
        Public Shared Function GetAllChildNodesOfResultNode(ByVal Node As LanguageElement, Optional ByVal DeepSearch As Boolean = True) As LanguageElementCollection
            Return New LEIterator(UsableTypes, DeepSearch).CollectElements(Node)
        End Function
        Public Shared Function GetAllNodesInSourceRange(ByVal Range As SourceRange, Optional ByVal DeepSearch As Boolean = True) As LanguageElementCollection
            Return New LEIterator(UsableTypes, False).CollectElements(Range)
        End Function

    End Class
End Namespace
